1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package sun.nio.ch;
27
28 import java.io.*;
29 import java.net.*;
30 import java.nio.*;
31 import java.nio.channels.*;
32
33
34
35
36
37
38
39
40
41 public class DatagramSocketAdaptor
42 extends DatagramSocket
43 {
44
45
46 private final DatagramChannelImpl dc;
47
48
49 private volatile int timeout = 0;
50
51
52 private DatagramSocketAdaptor(DatagramChannelImpl dc) throws IOException {
53
54
55
56
57 super(dummyDatagramSocket);
58 this.dc = dc;
59 }
60
61 public static DatagramSocket create(DatagramChannelImpl dc) {
62 try {
63 return new DatagramSocketAdaptor(dc);
64 } catch (IOException x) {
65 throw new Error(x);
66 }
67 }
68
69 private void connectInternal(SocketAddress remote)
70 throws SocketException
71 {
72 InetSocketAddress isa = Net.asInetSocketAddress(remote);
73 int port = isa.getPort();
74 if (port < 0 || port > 0xFFFF)
75 throw new IllegalArgumentException("connect: " + port);
76 if (remote == null)
77 throw new IllegalArgumentException("connect: null address");
78 if (isClosed())
79 return;
80 try {
81 dc.connect(remote);
82 } catch (Exception x) {
83 Net.translateToSocketException(x);
84 }
85 }
86
87 public void bind(SocketAddress local) throws SocketException {
88 try {
89 if (local == null)
90 local = new InetSocketAddress(0);
91 dc.bind(local);
92 } catch (Exception x) {
93 Net.translateToSocketException(x);
94 }
95 }
96
97 public void connect(InetAddress address, int port) {
98 try {
99 connectInternal(new InetSocketAddress(address, port));
100 } catch (SocketException x) {
101
102 }
103 }
104
105 public void connect(SocketAddress remote) throws SocketException {
106 if (remote == null)
107 throw new IllegalArgumentException("Address can't be null");
108 connectInternal(remote);
109 }
110
111 public void disconnect() {
112 try {
113 dc.disconnect();
114 } catch (IOException x) {
115 throw new Error(x);
116 }
117 }
118
119 public boolean isBound() {
120 return dc.localAddress() != null;
121 }
122
123 public boolean isConnected() {
124 return dc.remoteAddress() != null;
125 }
126
127 public InetAddress getInetAddress() {
128 return (isConnected()
129 ? Net.asInetSocketAddress(dc.remoteAddress()).getAddress()
130 : null);
131 }
132
133 public int getPort() {
134 return (isConnected()
135 ? Net.asInetSocketAddress(dc.remoteAddress()).getPort()
136 : -1);
137 }
138
139 public void send(DatagramPacket p) throws IOException {
140 synchronized (dc.blockingLock()) {
141 if (!dc.isBlocking())
142 throw new IllegalBlockingModeException();
143 try {
144 synchronized (p) {
145 ByteBuffer bb = ByteBuffer.wrap(p.getData(),
146 p.getOffset(),
147 p.getLength());
148 if (dc.isConnected()) {
149 if (p.getAddress() == null) {
150
151
152 InetSocketAddress isa = (InetSocketAddress)
153 dc.remoteAddress();
154 p.setPort(isa.getPort());
155 p.setAddress(isa.getAddress());
156 dc.write(bb);
157 } else {
158
159 dc.send(bb, p.getSocketAddress());
160 }
161 } else {
162
163 dc.send(bb, p.getSocketAddress());
164 }
165 }
166 } catch (IOException x) {
167 Net.translateException(x);
168 }
169 }
170 }
171
172
173
174 private SocketAddress receive(ByteBuffer bb) throws IOException {
175 if (timeout == 0) {
176 return dc.receive(bb);
177 }
178
179
180 SelectionKey sk = null;
181 Selector sel = null;
182 dc.configureBlocking(false);
183 try {
184 int n;
185 SocketAddress sender;
186 if ((sender = dc.receive(bb)) != null)
187 return sender;
188 sel = Util.getTemporarySelector(dc);
189 sk = dc.register(sel, SelectionKey.OP_READ);
190 long to = timeout;
191 for (;;) {
192 if (!dc.isOpen())
193 throw new ClosedChannelException();
194 long st = System.currentTimeMillis();
195 int ns = sel.select(to);
196 if (ns > 0 && sk.isReadable()) {
197 if ((sender = dc.receive(bb)) != null)
198 return sender;
199 }
200 sel.selectedKeys().remove(sk);
201 to -= System.currentTimeMillis() - st;
202 if (to <= 0)
203 throw new SocketTimeoutException();
204
205 }
206 } finally {
207 if (sk != null)
208 sk.cancel();
209 if (dc.isOpen())
210 dc.configureBlocking(true);
211 if (sel != null)
212 Util.releaseTemporarySelector(sel);
213 }
214 }
215
216 public void receive(DatagramPacket p) throws IOException {
217 synchronized (dc.blockingLock()) {
218 if (!dc.isBlocking())
219 throw new IllegalBlockingModeException();
220 try {
221 synchronized (p) {
222 ByteBuffer bb = ByteBuffer.wrap(p.getData(),
223 p.getOffset(),
224 p.getLength());
225 SocketAddress sender = receive(bb);
226 p.setSocketAddress(sender);
227 p.setLength(bb.position() - p.getOffset());
228 }
229 } catch (IOException x) {
230 Net.translateException(x);
231 }
232 }
233 }
234
235 public InetAddress getLocalAddress() {
236 if (isClosed())
237 return null;
238 SocketAddress local = dc.localAddress();
239 if (local == null)
240 local = new InetSocketAddress(0);
241 InetAddress result = ((InetSocketAddress)local).getAddress();
242 SecurityManager sm = System.getSecurityManager();
243 if (sm != null) {
244 try {
245 sm.checkConnect(result.getHostAddress(), -1);
246 } catch (SecurityException x) {
247 return new InetSocketAddress(0).getAddress();
248 }
249 }
250 return result;
251 }
252
253 public int getLocalPort() {
254 if (isClosed())
255 return -1;
256 try {
257 SocketAddress local = dc.getLocalAddress();
258 if (local != null) {
259 return ((InetSocketAddress)local).getPort();
260 }
261 } catch (Exception x) {
262 }
263 return 0;
264 }
265
266 public void setSoTimeout(int timeout) throws SocketException {
267 this.timeout = timeout;
268 }
269
270 public int getSoTimeout() throws SocketException {
271 return timeout;
272 }
273
274 private void setBooleanOption(SocketOption<Boolean> name, boolean value)
275 throws SocketException
276 {
277 try {
278 dc.setOption(name, value);
279 } catch (IOException x) {
280 Net.translateToSocketException(x);
281 }
282 }
283
284 private void setIntOption(SocketOption<Integer> name, int value)
285 throws SocketException
286 {
287 try {
288 dc.setOption(name, value);
289 } catch (IOException x) {
290 Net.translateToSocketException(x);
291 }
292 }
293
294 private boolean getBooleanOption(SocketOption<Boolean> name) throws SocketException {
295 try {
296 return dc.getOption(name).booleanValue();
297 } catch (IOException x) {
298 Net.translateToSocketException(x);
299 return false;
300 }
301 }
302
303 private int getIntOption(SocketOption<Integer> name) throws SocketException {
304 try {
305 return dc.getOption(name).intValue();
306 } catch (IOException x) {
307 Net.translateToSocketException(x);
308 return -1;
309 }
310 }
311
312 public void setSendBufferSize(int size) throws SocketException {
313 if (size <= 0)
314 throw new IllegalArgumentException("Invalid send size");
315 setIntOption(StandardSocketOptions.SO_SNDBUF, size);
316 }
317
318 public int getSendBufferSize() throws SocketException {
319 return getIntOption(StandardSocketOptions.SO_SNDBUF);
320 }
321
322 public void setReceiveBufferSize(int size) throws SocketException {
323 if (size <= 0)
324 throw new IllegalArgumentException("Invalid receive size");
325 setIntOption(StandardSocketOptions.SO_RCVBUF, size);
326 }
327
328 public int getReceiveBufferSize() throws SocketException {
329 return getIntOption(StandardSocketOptions.SO_RCVBUF);
330 }
331
332 public void setReuseAddress(boolean on) throws SocketException {
333 setBooleanOption(StandardSocketOptions.SO_REUSEADDR, on);
334 }
335
336 public boolean getReuseAddress() throws SocketException {
337 return getBooleanOption(StandardSocketOptions.SO_REUSEADDR);
338
339 }
340
341 public void setBroadcast(boolean on) throws SocketException {
342 setBooleanOption(StandardSocketOptions.SO_BROADCAST, on);
343 }
344
345 public boolean getBroadcast() throws SocketException {
346 return getBooleanOption(StandardSocketOptions.SO_BROADCAST);
347 }
348
349 public void setTrafficClass(int tc) throws SocketException {
350 setIntOption(StandardSocketOptions.IP_TOS, tc);
351 }
352
353 public int getTrafficClass() throws SocketException {
354 return getIntOption(StandardSocketOptions.IP_TOS);
355 }
356
357 public void close() {
358 try {
359 dc.close();
360 } catch (IOException x) {
361 throw new Error(x);
362 }
363 }
364
365 public boolean isClosed() {
366 return !dc.isOpen();
367 }
368
369 public DatagramChannel getChannel() {
370 return dc;
371 }
372
373
374
375
376
377
378 private static final DatagramSocketImpl dummyDatagramSocket
379 = new DatagramSocketImpl()
380 {
381 protected void create() throws SocketException {}
382
383 protected void bind(int lport, InetAddress laddr) throws SocketException {}
384
385 protected void send(DatagramPacket p) throws IOException {}
386
387 protected int peek(InetAddress i) throws IOException { return 0; }
388
389 protected int peekData(DatagramPacket p) throws IOException { return 0; }
390
391 protected void receive(DatagramPacket p) throws IOException {}
392
393 protected void setTTL(byte ttl) throws IOException {}
394
395 protected byte getTTL() throws IOException { return 0; }
396
397 protected void setTimeToLive(int ttl) throws IOException {}
398
399 protected int getTimeToLive() throws IOException { return 0;}
400
401 protected void join(InetAddress inetaddr) throws IOException {}
402
403 protected void leave(InetAddress inetaddr) throws IOException {}
404
405 protected void joinGroup(SocketAddress mcastaddr,
406 NetworkInterface netIf) throws IOException {}
407
408 protected void leaveGroup(SocketAddress mcastaddr,
409 NetworkInterface netIf) throws IOException {}
410
411 protected void close() {}
412
413 public Object getOption(int optID) throws SocketException { return null;}
414
415 public void setOption(int optID, Object value) throws SocketException {}
416 };
417 }